#include "DOpenGLCamera.h"


DOpenGLCamera::DOpenGLCamera(void)
{
	projectionMatrix=glm::mat4(1.0f);
	viewMatrix=glm::mat4(1.0f);
	overallTransformMatrix=glm::mat4(1.0f);
	dragingType = DRAG_NONE;
	viewPortScale = 7.0;
	viewCenter=glm::vec3(0,0,0);
	viewRotation=glm::vec3(0,0,0);

	viewRotation.x = M_PI/2;
	viewRotation.y = 0.5;


	CalcViewMatrix();

}


DOpenGLCamera::~DOpenGLCamera(void)
{
}

void DOpenGLCamera::StartDrag(int mouse_x, int mouse_y, DragingType type)
{
	dragingType = type;
	draging_ox = mouse_x;
	draging_oy = mouse_y;
}
void DOpenGLCamera::Drag(int mouse_x, int mouse_y)
{
	int dx = mouse_x - draging_ox;
	int dy = mouse_y - draging_oy;
	draging_ox = mouse_x;
	draging_oy = mouse_y;
	if(dragingType == DRAG_ROTATE)
	{
		viewRotation.x += dx / 2000.0f * viewPortScale;
        viewRotation.y += dy / 2000.0f * viewPortScale;
		if(viewRotation.y > 1.57)viewRotation.y = 1.57;
		if(viewRotation.y < -1.57)viewRotation.y = -1.57;
		CalcViewMatrix();
	}
	else if(dragingType == DRAG_TRANSLATE)
	{
		viewCenter += viewDir_right * (-dx / 2000.0f) * viewPortScale;
		viewCenter += viewDir_up * (dy / 2000.0f)  * viewPortScale;
		CalcViewMatrix();
	}
	else if(dragingType == DRAG_ZOOM)
	{
		viewPortScale *= expf(dy / 2000.0f);
		CalcViewMatrix();
	}
	else 
	{
		return;
	}
	overallTransformMatrix = projectionMatrix * viewMatrix;

}
void DOpenGLCamera::StopDrag()
{
	dragingType = DRAG_NONE;
}

const float* DOpenGLCamera::GetProjectionMatrixDataPtr() const
{
	return glm::value_ptr(projectionMatrix);
}
const float* DOpenGLCamera::GetViewMatrixDataPtr() const
{
	return glm::value_ptr(viewMatrix);
}

void DOpenGLCamera::CalcViewMatrix()
{
	const float R = 20.0f;
	viewPosition.x = viewCenter.x + R*cos(viewRotation.y)*cos(viewRotation.x);
	viewPosition.y = viewCenter.y + R*cos(viewRotation.y)*sin(viewRotation.x);
	viewPosition.z = viewCenter.z + R*sin(viewRotation.y);

	float vx = -viewPosition.x + viewCenter.x;
	float vy = -viewPosition.y + viewCenter.y;
	float vz = -viewPosition.z + viewCenter.z;
	viewDir_right.x = -vy;
	viewDir_right.y = vx;
	viewDir_right.z = 0;

	viewDir_up = glm::cross(viewDir_right,glm::vec3(-vx,-vy,-vz));
	viewDir_right = glm::normalize(viewDir_right);
	viewDir_up = glm::normalize(viewDir_up);
	//projectionMatrix = glm::perspective<float>(viewPortScale,4.0f/3.0f,0,20);
	projectionMatrix = glm::ortho<float>(-viewPortScale, viewPortScale, -viewPortScale, viewPortScale, 0, 1000.0);
	viewMatrix = glm::lookAt<float>(viewPosition,viewCenter,viewDir_up);
}
